package parameters;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.util.Properties;

import utils.NetworkUtils;

public final class RLM_Parameters implements RLM_DefaultParameterValues {

	public static final String APP_NAME		= "RLM";


	/**
	 * This method returns platform dependent RLM application data folder name.
	 * @return app. data folder name
	 */
	public static final String getApplicationDataFolderName() {
		String appData = "";
		String osName = System.getProperty("os.name");
		String userHome = System.getProperty("user.home");
		
		if (System.getProperty("configDir") != null) {
		    appData = System.getProperty("configDir");
        }
		// if true, Windows platform
		else if ( osName.startsWith("Windows") ) {
			appData = userHome + File.separator + "Application Data" + File.separator + APP_NAME;
		}
		// otherwise, Linux or Unix platform
		else {
			// . to be hidden
			appData = userHome + "/." + APP_NAME.toLowerCase();
		}

		return appData;
	}
	
	
	private static final String propertiesFileName = "RLM.properties";
	private static final String propFileName = getApplicationDataFolderName() + "/" + propertiesFileName;
	
	
	/**
	 * Private constructor.
	 */
	private RLM_Parameters() { }
	
	
	private static int width;
	private static int height;
	private static int location_x;
	private static int location_y;
	private static boolean alwaysOnTop;
	private static String username;
	private static String password;
	private static String receivedFolder;
	private static String serverName;
	private static int serverPort;
	private static int status;
	private static String fontName;
	private static int fontStyle;
	private static int fontSize;
	private static int fontColor_R;
	private static int fontColor_G;
	private static int fontColor_B;
	private static int backgroundColor_R;
	private static int backgroundColor_G;
	private static int backgroundColor_B;
	private static boolean firstStart;
	private static boolean splashScreen;
	
	private static String networkInterfaceToConnect;
	private static String macAddress;
	
	private static int tcpPort;
	private static int audioPort;
	private static int videoPort;
	
	private static boolean isLan;
	
	private static String audioDevice;
	private static String videoDevice;
	
	
	/**
	 * This method creates "RLM.properties" that stores RLM parameters with
	 * default values.
	 * @author UrosKrkic & Radivoje Popovic
	 */
	public static void createDefaultParameters() {
		Properties properties = new Properties();

		properties.setProperty("width", intToString(WIDTH));
		properties.setProperty("height", intToString(HEIGHT));
		properties.setProperty("location_x", intToString(LOCATION_X));
		properties.setProperty("location_y", intToString(LOCATION_Y));
		properties.setProperty("alwaysOnTop", booleanToString(ALWAYS_ON_TOP));
		properties.setProperty("username", USERNAME);
		properties.setProperty("password", PASSWORD);
		properties.setProperty("receivedFolder", RECEIVED_FOLDER);
		properties.setProperty("serverName", SERVER_NAME);
		properties.setProperty("serverPort", intToString(SERVER_PORT));
		properties.setProperty("status", intToString(STATUS));
		properties.setProperty("fontName", FONT_NAME);
		properties.setProperty("fontStyle", intToString(FONT_STYLE));
		properties.setProperty("fontSize", intToString(FONT_SIZE));
		properties.setProperty("fontColor_R", intToString(FONT_COLOR_R));
		properties.setProperty("fontColor_G", intToString(FONT_COLOR_G));
		properties.setProperty("fontColor_B", intToString(FONT_COLOR_B));
		properties.setProperty("backgroundColor_R", intToString(BACKGROUND_COLOR_R));
		properties.setProperty("backgroundColor_G", intToString(BACKGROUND_COLOR_G));
		properties.setProperty("backgroundColor_B", intToString(BACKGROUND_COLOR_B));
		properties.setProperty("splashScreen", booleanToString(SPLASH_SCREEN));
		properties.setProperty("firstStart", booleanToString(FIRST_START));
		properties.setProperty("splashScreen", booleanToString(SPLASH_SCREEN));

		properties.setProperty("autoStart", booleanToString(AUTO_START));

		properties.setProperty("networkInterfaceToConnect", NIC_AUTO_SELECT);
		properties.setProperty("macAddress", MAC_ADDRESS);
		
		properties.setProperty("tcpPort", intToString(CLIENT_SERVER_TCP_PORT));
		properties.setProperty("audioPort", intToString(CLIENT_AUDIO_PORT));
		properties.setProperty("videoPort", intToString(CLIENT_VIDEO_PORT));
		
		properties.setProperty("isLan", booleanToString(IS_LAN));
		
		properties.setProperty("audioDevice", AUDIO_DEVICE);
		properties.setProperty("videoDevice", VIDEO_DEVICE);

		File propertiesFile = new File(propFileName);

		try {
			propertiesFile.createNewFile();
			properties.store(new FileOutputStream(propertiesFile), "RLM");
		}
		catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}


	/**
	 * This method loads RLM parameters from external file - RLM.properties.
	 * @author UrosKrkic & Radivoje Popovic
	 */
	public static void loadParameters() {

		File propertiesFile = new File(propFileName);

		if ( !propertiesFile.exists() ) {
			createDefaultParameters();
		}

		Properties properties = new Properties();

		try {
			properties.load(new FileInputStream(propertiesFile));

		}
		catch (FileNotFoundException e) {
			e.printStackTrace();
			return;
		}
		catch (IOException e) {
			e.printStackTrace();
			return;
		}

		try {
			width = Integer.parseInt( properties.getProperty("width", intToString(WIDTH)) );
		}
		catch (NumberFormatException nfe) {
			width = WIDTH;
		}
		
		try {
			height = Integer.parseInt( properties.getProperty("height", intToString(HEIGHT)) );
		}
		catch (NumberFormatException nfe) {
			height = HEIGHT;
		}
		
		try {
			location_x = Integer.parseInt( properties.getProperty("location_x", intToString(LOCATION_X)) );
		}
		catch (NumberFormatException nfe) {
			location_x = LOCATION_X;
		}
		
		try {
			location_y = Integer.parseInt( properties.getProperty("location_y", intToString(LOCATION_Y)) );
		}
		catch (NumberFormatException nfe) {
			location_y = LOCATION_Y;
		}
		
		alwaysOnTop = Boolean.parseBoolean( properties.getProperty("alwaysOnTop", booleanToString(ALWAYS_ON_TOP)) );
		
		username = properties.getProperty("username", USERNAME);
		password = properties.getProperty("password", PASSWORD);
		
		receivedFolder = properties.getProperty("receivedFolder", RECEIVED_FOLDER);
		
		serverName = properties.getProperty("serverName", SERVER_NAME);
		
		try {
			serverPort = Integer.parseInt( properties.getProperty("serverPort", intToString(SERVER_PORT)) );
		}
		catch (NumberFormatException nfe) {
			serverPort = SERVER_PORT;
		}

		
		try {
			status = Integer.parseInt( properties.getProperty("status", intToString(STATUS)) );
		}
		catch (NumberFormatException nfe) {
			status = STATUS;
		}

		
		fontName = properties.getProperty("fontName", FONT_NAME);
		try {
			fontStyle = Integer.parseInt( properties.getProperty("fontStyle", intToString(FONT_STYLE)) );
		}
		catch (NumberFormatException nfe) {
			fontStyle = FONT_STYLE;
		}
		try {
			fontSize = Integer.parseInt( properties.getProperty("fontSize", intToString(FONT_SIZE)) );
		}
		catch (NumberFormatException nfe) {
			fontSize = FONT_SIZE;
		}
		try {
			fontColor_R = Integer.parseInt( properties.getProperty("fontColor_R", intToString(FONT_COLOR_R)) );
		}
		catch (NumberFormatException nfe) {
			fontColor_R = FONT_COLOR_R;
		}
		try {
			fontColor_G = Integer.parseInt( properties.getProperty("fontColor_G", intToString(FONT_COLOR_G)) );
		}
		catch (NumberFormatException nfe) {
			fontColor_G = FONT_COLOR_G;
		}
		try {
			fontColor_B = Integer.parseInt( properties.getProperty("fontColor_B", intToString(FONT_COLOR_B)) );
		}
		catch (NumberFormatException nfe) {
			fontColor_B = FONT_COLOR_B;
		}
		
		
		try {
			backgroundColor_R = Integer.parseInt( properties.getProperty("backgroundColor_R", intToString(BACKGROUND_COLOR_R)) );
		}
		catch (NumberFormatException nfe) {
			backgroundColor_R = BACKGROUND_COLOR_R;
		}
		try {
			backgroundColor_G = Integer.parseInt( properties.getProperty("backgroundColor_G", intToString(BACKGROUND_COLOR_G)) );
		}
		catch (NumberFormatException nfe) {
			backgroundColor_G = BACKGROUND_COLOR_G;
		}
		try {
			backgroundColor_B = Integer.parseInt( properties.getProperty("backgroundColor_B", intToString(BACKGROUND_COLOR_B)) );
		}
		catch (NumberFormatException nfe) {
			backgroundColor_B = BACKGROUND_COLOR_B;
		}

		splashScreen = Boolean.parseBoolean( properties.getProperty("splashScreen", booleanToString(SPLASH_SCREEN)) );
		firstStart = Boolean.parseBoolean( properties.getProperty("firstStart", booleanToString(FIRST_START)) );
		
		networkInterfaceToConnect = properties.getProperty("networkInterfaceToConnect", NIC_AUTO_SELECT);
		macAddress = properties.getProperty("macAddress", MAC_ADDRESS);
		
		try {
			tcpPort = Integer.parseInt( properties.getProperty("tcpPort", intToString(CLIENT_SERVER_TCP_PORT)) );
		}
		catch (NumberFormatException nfe) {
			tcpPort = CLIENT_SERVER_TCP_PORT;
		}
		
		try {
			audioPort = Integer.parseInt( properties.getProperty("audioPort", intToString(CLIENT_AUDIO_PORT)) );
		}
		catch (NumberFormatException nfe) {
			audioPort = CLIENT_AUDIO_PORT;
		}
		
		try {
			videoPort = Integer.parseInt( properties.getProperty("videoPort", intToString(CLIENT_VIDEO_PORT)) );
		}
		catch (NumberFormatException nfe) {
			videoPort = CLIENT_VIDEO_PORT;
		}
		
		isLan = Boolean.parseBoolean( properties.getProperty("isLan", booleanToString(IS_LAN)) );
	
		audioDevice = properties.getProperty("audioDevice", AUDIO_DEVICE);
		videoDevice = properties.getProperty("videoDevice", VIDEO_DEVICE);
	}


	/**
	 * This method stores RLM parameters to external file - RLM.properties.
	 * @author UrosKrkic & Radivoje Popovic
	 */
	public static void storeParameters() {

		Properties properties = new Properties();

		properties.setProperty("width", intToString(width));
		properties.setProperty("height", intToString(height));
		properties.setProperty("location_x", intToString(location_x));
		properties.setProperty("location_y", intToString(location_y));
		properties.setProperty("alwaysOnTop", booleanToString(alwaysOnTop));
		properties.setProperty("username", username);
		properties.setProperty("password", password);
		properties.setProperty("receivedFolder", receivedFolder);
		properties.setProperty("serverName", serverName);
		properties.setProperty("serverPort", intToString(serverPort));
		properties.setProperty("status", intToString(status));
		properties.setProperty("fontName", fontName);
		properties.setProperty("fontStyle", intToString(fontStyle));
		properties.setProperty("fontSize", intToString(fontSize));
		properties.setProperty("fontColor_R", intToString(fontColor_R));
		properties.setProperty("fontColor_G", intToString(fontColor_G));
		properties.setProperty("fontColor_B", intToString(fontColor_B));
		properties.setProperty("backgroundColor_R", intToString(backgroundColor_R));
		properties.setProperty("backgroundColor_G", intToString(backgroundColor_G));
		properties.setProperty("backgroundColor_B", intToString(backgroundColor_B));
		properties.setProperty("firstStart", booleanToString(firstStart));
		properties.setProperty("splashScreen", booleanToString(splashScreen));

//		properties.setProperty("autoStart", booleanToString(autoStart));
		
		properties.setProperty("networkInterfaceToConnect", networkInterfaceToConnect);
		properties.setProperty("macAddress", macAddress);
		
		properties.setProperty("tcpPort", intToString(tcpPort));
		properties.setProperty("audioPort", intToString(audioPort));
		properties.setProperty("videoPort", intToString(videoPort));
		
		properties.setProperty("isLan", booleanToString(isLan));
		
		properties.setProperty("audioDevice", audioDevice);
		properties.setProperty("videoDevice", videoDevice);
		

		File propertiesFile = new File(propFileName);

		try {
			if ( !propertiesFile.exists() ) {
				propertiesFile.createNewFile();
			}

			properties.store(new FileOutputStream(propertiesFile), "RLM");
		}
		catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}


	public static int getWidth() {
		return width;
	}


	public static void setWidth(int width) {
		RLM_Parameters.width = width;
	}


	public static int getHeight() {
		return height;
	}


	public static void setHeight(int height) {
		RLM_Parameters.height = height;
	}


	public static int getLocation_x() {
		return location_x;
	}


	public static void setLocation_x(int location_x) {
		RLM_Parameters.location_x = location_x;
	}


	public static int getLocation_y() {
		return location_y;
	}


	public static void setLocation_y(int location_y) {
		RLM_Parameters.location_y = location_y;
	}


	public static boolean isAlwaysOnTop() {
		return alwaysOnTop;
	}


	public static void setAlwaysOnTop(boolean alwaysOnTop) {
		RLM_Parameters.alwaysOnTop = alwaysOnTop;
	}


	public static String getUsername() {
		return username;
	}


	public static void setUsername(String username) {
		RLM_Parameters.username = username;
	}


	public static String getPassword() {
		return password;
	}


	public static void setPassword(String password) {
		RLM_Parameters.password = password;
	}


	public static String getReceivedFolder() {
		return receivedFolder;
	}


	public static void setReceivedFolder(String receivedFolder) {
		RLM_Parameters.receivedFolder = receivedFolder;
	}


	public static String getServerName() {
		return serverName;
	}


	public static void setServerName(String serverName) {
		RLM_Parameters.serverName = serverName;
	}


	public static int getServerPort() {
		return serverPort;
	}


	public static void setServerPort(int serverPort) {
		RLM_Parameters.serverPort = serverPort;
	}


	public static int getStatus() {
		return status;
	}


	public static void setStatus(int status) {
		RLM_Parameters.status = status;
	}


	public static String getFontName() {
		return fontName;
	}


	public static void setFontName(String fontName) {
		RLM_Parameters.fontName = fontName;
	}


	public static int getFontStyle() {
		return fontStyle;
	}


	public static void setFontStyle(int fontStyle) {
		RLM_Parameters.fontStyle = fontStyle;
	}


	public static int getFontSize() {
		return fontSize;
	}


	public static void setFontSize(int fontSize) {
		RLM_Parameters.fontSize = fontSize;
	}


	public static int getFontColor_R() {
		return fontColor_R;
	}


	public static void setFontColor_R(int fontColor_R) {
		RLM_Parameters.fontColor_R = fontColor_R;
	}


	public static int getFontColor_G() {
		return fontColor_G;
	}


	public static void setFontColor_G(int fontColor_G) {
		RLM_Parameters.fontColor_G = fontColor_G;
	}


	public static int getFontColor_B() {
		return fontColor_B;
	}


	public static void setFontColor_B(int fontColor_B) {
		RLM_Parameters.fontColor_B = fontColor_B;
	}


	public static int getBackgroundColor_R() {
		return backgroundColor_R;
	}


	public static void setBackgroundColor_R(int backgroundColor_R) {
		RLM_Parameters.backgroundColor_R = backgroundColor_R;
	}


	public static int getBackgroundColor_G() {
		return backgroundColor_G;
	}


	public static void setBackgroundColor_G(int backgroundColor_G) {
		RLM_Parameters.backgroundColor_G = backgroundColor_G;
	}


	public static int getBackgroundColor_B() {
		return backgroundColor_B;
	}


	public static void setBackgroundColor_B(int backgroundColor_B) {
		RLM_Parameters.backgroundColor_B = backgroundColor_B;
	}


	public static boolean isFirstStart() {
		return firstStart;
	}


	public static void setFirstStart(boolean firstStart) {
		RLM_Parameters.firstStart = firstStart;
	}
	
	
	
	private static String intToString(int value) {
		return Integer.toString(value);
	}

	private static String booleanToString(boolean value) {
		return Boolean.toString(value);
	}


	public static boolean isSplashScreen() {
		return splashScreen;
	}


	public static void setSplashScreen(boolean splashScreen) {
		RLM_Parameters.splashScreen = splashScreen;
	}

	
	public static String getNetworkInterfaceToConnect() {
		return getNetworkInterfaceToConnect(false);
	}

	public static String getNetworkInterfaceToConnect(boolean flag) {
		
		if ( networkInterfaceToConnect.equals("null") )
			return null;
		
		if (flag == true) {
			return networkInterfaceToConnect;
		}

		if ( networkInterfaceToConnect.equals(NIC_AUTO_SELECT) ) {
			InetAddress ia = NetworkUtils.getLocalAddress();
			
			if (ia == null)
				return null;
			
			return ia.getHostAddress();
		}
		
		return networkInterfaceToConnect;
	}


	public static void setNetworkInterfaceToConnect(String networkInterfaceToConnect) {
		RLM_Parameters.networkInterfaceToConnect = networkInterfaceToConnect;
	}
	
	public static boolean isNICAutoSelect() {
		return networkInterfaceToConnect.equals(NIC_AUTO_SELECT);
	}
	
	public static String getMACAddress() {
		return macAddress;
	}
	
	public static void setMACAddress(String macAddress) {
		RLM_Parameters.macAddress = macAddress;
	}


	public static int getTcpPort() {
		return tcpPort;
	}


	public static void setTcpPort(int tcpPort) {
		RLM_Parameters.tcpPort = tcpPort;
	}


	public static int getAudioPort() {
		return audioPort;
	}


	public static void setAudioPort(int audioPort) {
		RLM_Parameters.audioPort = audioPort;
	}


	public static boolean isLan() {
		return isLan;
	}


	public static void setLan(boolean isLan) {
		RLM_Parameters.isLan = isLan;
	}


	public static int getVideoPort() {
		return videoPort;
	}


	public static void setVideoPort(int videoPort) {
		RLM_Parameters.videoPort = videoPort;
	}


	public static String getAudioDevice() {
		return audioDevice;
	}


	public static void setAudioDevice(String audioDevice) {
		RLM_Parameters.audioDevice = audioDevice;
	}


	public static String getVideoDevice() {
		return videoDevice;
	}


	public static void setVideoDevice(String videoDevice) {
		RLM_Parameters.videoDevice = videoDevice;
	}
}
